中间件

怎样自己写一个中间件?

比如有以下需求

  • 通过该中间件去统计请求数目、状态和时间。
  • 中间件把写过写回响应。

Server

server.go

package main

import
(
"net/http"
"strconv"
"sync"
"time"
"github.com/labstack/echo"
)

type
(
    Stats struct{
        Uptime       time.Time      `json:"uptime"`
        RequestCount uint64 `json:"requestCount"`
        Statuses     map[string]int `json:"statuses"`
        mutex        sync.RWMutex    
        }
)

func NewStats()*Stats {
    return &Stats{ Uptime: time.Now(), Statuses:make(map[string]int),}
}
// Process is the middleware function.
func(s *Stats) Process(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error{
        if err := next(c); err !=nil{
            c.Error(err)
        }
        s.mutex.Lock()
        defer s.mutex.Unlock()
        s.RequestCount++
        status := strconv.Itoa(c.Response().Status)
        s.Statuses[status]++
        return nil
    }
}
// Handle is the endpoint to get stats.
func(s *Stats) Handle(c echo.Context) error{
    s.mutex.RLock()
    defer s.mutex.RUnlock()
    return c.JSON(http.StatusOK, s)
}

// ServerHeader middleware adds a `Server` header to the response.
func ServerHeader(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error{
        c.Response().Header().Set(echo.HeaderServer, "Echo/3.0")
        return next(c)
        }
}

func main(){
    e := echo.New()
    // Debug mode
    e.Debug =true
    //-------------------
    // Custom middleware
    //-------------------
    // Stats
    s :=NewStats()
    e.Use(s.Process)
    e.GET("/stats", s.Handle)
    // Endpoint to get stats
    // Server header
    e.Use(ServerHeader)
    // Handler
    e.GET("/",func(c echo.Context) error{
        return c.String(http.StatusOK,"Hello, World!")
        })
    // Start server
    e.Logger.Fatal(e.Start(":1323"))
}

响应

响应头

Content-Length:122
Content-Type:application/json; charset=utf-8
Date:Thu, 14 Apr 2016 20:31:46 GMT
Server:Echo/2.0

响应体

{
"uptime":"2016-04-14T13:28:48.486548936-07:00",
"requestCount":5,
"statuses":{
    "200":4,
    "404":1
    }
}

results matching ""

    No results matching ""